#ifndef DATAADAPTERS_H_
#define DATAADAPTERS_H_

#include <s32strm.h> 

#include "scatu/DataAdaptersBase.h"

/* Basic data adapters are in DataAdaptersBase.h
 * 
 * The following example works both as a template for defining new adapters
 * and as documentation to how adapters should work:
 *  

template<>
class RDataAdapter<YourType>
    {
public:
    typedef ... ArgType;       <-- type which is passed as argument 
    typedef ... ReturnType;    <-- type which is returned from function
    typedef ... ReferenceType; <-- reference to object
    
    // Copies value of object or stores a reference
    RDataAdapter(ArgType) { ... }
    
    // Takes ownership of object
    RDataAdapter(ReturnType) { ... }
    
    // Default ctor inits to whatever is suitable
    RDataAdapter() { ... }
    
    // Free all resources
    void Close() { ... } 
    
    // These two are self expanatory
    void ExternalizeL(RWriteStream& aStream) const { ... }
    void InternalizeL(RReadStream& aStream) { ... }
    
    // Returns a reference to contained object.
    // This is reference is safe only during the lifetime of the data adapter.
    ReferenceType Reference() const { ... }
    
    // Passes ownership to caller.
    ReturnType AdoptL() { ... }
    
    };
*/


namespace scatu {

#define DEFINE_DES_ADAPTER(DesType, BufType, PtrType) \
template<> \
class RDataAdapter<DesType> : public RDesAdapter<DesType, BufType, PtrType> { \
public: \
    RDataAdapter() : RDesAdapter<DesType, BufType, PtrType>() {} \
    RDataAdapter(ReferenceType aValue) \
      : RDesAdapter<DesType, BufType, PtrType>(aValue) {} \
    RDataAdapter(ReturnType aValue) \
      : RDesAdapter<DesType, BufType, PtrType>(aValue) {} \
    };
    
DEFINE_DES_ADAPTER(TDesC, HBufC, TPtr)
DEFINE_DES_ADAPTER(TDesC8, HBufC8, TPtr8)

#define DEFINE_INTEGRAL_ADAPTER(TemplateType, SerializeType, ExternalizeFunc, InternalizeFunc) \
template<> \
class RDataAdapter<TemplateType> : public RDataAdapterIntegral<TemplateType, SerializeType> { \
public: \
    RDataAdapter() : RDataAdapterIntegral<TemplateType, SerializeType>(ExternalizeFunc, InternalizeFunc) {} \
    RDataAdapter(TemplateType aValue) \
      : RDataAdapterIntegral<TemplateType, SerializeType>(aValue, ExternalizeFunc, InternalizeFunc) {} \
    };

DEFINE_INTEGRAL_ADAPTER(TInt, TInt32, &RWriteStream::WriteInt32L, &RReadStream::ReadInt32L)
// TBool is typedeffed as TInt, so we can't make it its own class...

template<>
class RDataAdapter<TUid>
    {
public:
    
    typedef TUid ArgType;
    typedef TUid ReturnType;
    
    RDataAdapter(TUid aValue)
      : iValue(aValue) {}
    
    RDataAdapter()
      : iValue(TUid::Null()) {}
    
    void Close() {}
    
    void ExternalizeL(RWriteStream& aStream) const
        {
        aStream.WriteInt32L(iValue.iUid);
        }
    
    void InternalizeL(RReadStream& aStream)
        {
        iValue = TUid::Uid(aStream.ReadInt32L());
        }
    
    operator TUid () const
        {
        return iValue;
        }
    
private:
    TUid iValue;
    };

} // namespace scatu

#endif /* DATAADAPTERS_H_ */
